package draftProjects;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.jdo.PersistenceManager;
import javax.servlet.http.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.*;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

@SuppressWarnings("serial")
public class SaveTableServlet extends HttpServlet {
	private static final Logger log = Logger.getLogger(SaveTableServlet.class.getName());
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
        resp.setContentType("text/plain"); 
        resp.getWriter().println("Get Method"); 
	}
	
	public void doPost(HttpServletRequest req, HttpServletResponse resp) 
		throws  IOException {  

		resp.setContentType("text/plain"); 

		String xmlData = req.getParameter("data");
		Document xmlDoc = CreateDocument(xmlData);
		Table table = CreateTable(xmlDoc);
		
        if(table == null){
        	log.severe("SaveTableServlet.doPost: table is null");
	        resp.getWriter().println("Error"); 
        }else{
        	SaveTable(table);
	        resp.getWriter().println("Ok"); 
        }
	}           	
	
	private Document CreateDocument(String xmlData)
	{
		Document result = null;
		
		if(xmlData == null){
			log.severe("CreateDocument: xmlData is null.");
		}
		else
		{
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			try {
				DocumentBuilder db = dbf.newDocumentBuilder();
				result = db.parse(new ByteArrayInputStream(xmlData.getBytes("UTF-8")));
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		return result;
	}
	
	private void SaveTable(Table table)
	{
       if(table == null){
        	log.severe("SaveTable: table is null");
       }else{
	        PersistenceManager pm = PMF.get().getPersistenceManager(); 
	        try {
	        	for(int i = 0; i<table.GetRawCount(); i++)
	        	{
	        		pm.makePersistent(table.GetRaw(i));
	        	}
	        } finally { 
	            pm.close(); 
	        } 
       }
	}
	
	private Table CreateTable(Document xmlDoc)
	{
		Table result = null;
		
		if(xmlDoc == null){
			log.severe("CreateTable: xmlDoc is null.");
		}
		else
		{
			NodeList tableNodeList = xmlDoc.getElementsByTagName("table");
			if(tableNodeList.getLength()==1)
			{
				Element tableNode = (Element) tableNodeList.item(0);
				
				Date crawlDate = new Date();
				NodeList crawDateList = tableNode.getElementsByTagName("crawldate");
				if(crawDateList.getLength() == 1){
					String s_crawlDate = crawDateList.item(0).getAttributes().getNamedItem("value").getTextContent();
					SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd HH:mm");
					try {
						crawlDate = dateFormat.parse(s_crawlDate);
					} catch (ParseException e) {
						log.severe(String.format("CreateTable: cannot parse crawlDate: %s.", s_crawlDate));
					}
				}else{
					log.severe(String.format("CreateTable: xml document has %d 'crawldate' nodes",  crawDateList.getLength()));
				}

				NodeList rawsList = tableNode.getElementsByTagName("raw");
				if(rawsList.getLength() == 250){
					result = new Table(crawlDate);
					for(int i=0; i<250; i++)
					{
						Node xmlRaw = rawsList.item(i);
						
						int place = i+1;
						Node xmlPlace = xmlRaw.getAttributes().getNamedItem("place");
						if(xmlPlace != null)
						{
							try{
							place = Integer.parseInt(xmlPlace.getTextContent());
							} catch (NumberFormatException e) {
								log.severe(String.format("CreateTable: cannot parse place attribute in %d raw: %s"
										, i, xmlPlace.getTextContent()));
							}
						}
						else
						{
							log.severe(String.format("CreateTable: cannot get place attribute in %d raw", i));
						}

						String name = "";
						Node xmlName = xmlRaw.getAttributes().getNamedItem("name");
						if(xmlName != null)
						{
							name = xmlName.getTextContent();
						}
						else
						{
							log.severe(String.format("CreateTable: cannot get name attribute in %d raw", i));
						}

						String originalName = "";
						Node xmlOriginalName = xmlRaw.getAttributes().getNamedItem("originalName");
						if(xmlOriginalName != null)
						{
							originalName = xmlOriginalName.getTextContent();
						}
						else
						{
							log.severe(String.format("CreateTable: cannot get originalName attribute in %d raw", i));
						}

						String href = "";
						Node xmlHref = xmlRaw.getAttributes().getNamedItem("href");
						if(xmlHref != null)
						{
							href = xmlHref.getTextContent();
						}
						else
						{
							log.severe(String.format("CreateTable: cannot get href attribute in %d raw", i));
						}

						int votes = 0;
						Node xmlVotes = xmlRaw.getAttributes().getNamedItem("votes");
						if(xmlVotes != null)
						{
							try{
								votes = Integer.parseInt(xmlVotes.getTextContent());
							} catch (NumberFormatException e) {
								log.severe(String.format("CreateTable: cannot parse votes attribute in %d raw: %s"
										, i, xmlVotes.getTextContent()));
							}
						}
						else
						{
							log.severe(String.format("CreateTable: cannot get votes attribute in %d raw", i));
						}

						double rating = 0;
						Node xmlRating = xmlRaw.getAttributes().getNamedItem("rating");
						if(xmlRating != null)
						{
							try{
								rating = Double.parseDouble(xmlRating.getTextContent());
							} catch (NumberFormatException e) {
								log.severe(String.format("CreateTable: cannot parse rating attribute in %d raw: %s"
										, i, xmlRating.getTextContent()));
							}
						}
						else
						{
							log.severe(String.format("CreateTable: cannot get rating attribute in %d raw", i));
						}
						
						Raw raw = new Raw(place, name, originalName, href, rating, votes, crawlDate);
						result.AddRaw(raw);
					}
				}else{
					log.severe(String.format("CreateTable: xml document has %d 'raw' nodes",  rawsList.getLength()));
				}
			}else{
				log.severe(String.format("CreateTable: xml document has %d 'table' nodes",  tableNodeList.getLength()));
			}
		}
		return result;
	}
}